# -*- coding: utf-8 -*-
"""
中性策略框架 | 邢不行 | 2024分享会
author: 邢不行
微信: xbx6660
"""
import traceback
import platform
import subprocess
import ntplib
import time
from time import ctime
from datetime import datetime
from utils.dingding import send_wechat_work_msg
from utils.commons import sleep_until_run_time
from config import error_webhook_url


def sync_time_ntp():
    """
    用于Linux和Mac同步系统时间
    默认添加了一些较为常见的ntp时间同步服务器，可以自行修改
    """
    ntp_servers = ['time.apple.com', 'ntp.aliyun.com', 'pool.ntp.org', 'time.google.com', 'time.windows.com']
    for ntp_server in ntp_servers:
        c = ntplib.NTPClient()
        try:
            response = c.request(ntp_server, timeout=5, version=3)  # 请求并同步时间
            timestamp = response.tx_time  # 获取ntp服务器的时间
            datetime_object = datetime.fromtimestamp(timestamp)
            datetime_string = datetime_object.strftime('%Y-%m-%d %H:%M:%S')
            current_time = ctime()  # 调用ctime函数来获取当前时间
            print(f'从NTP服务器{ntp_server}获取的时间为:', datetime_string)
            print('已同步到服务器时间:', current_time)
            break  # 如果成功同步一个服务器，退出循环
        except ntplib.NTPException as e:
            print(f'NTP服务器{ntp_server}请求超时或发生其他NTP异常:', str(e))
        except Exception as e:
            print(f'与NTP服务器{ntp_server}通信时发生错误:', str(e))


def sync_time_windows():
    """
    用于windows同步系统时间
    注意windows情况下，需要使用管理员身份运行脚本才可以。
    这里运行的时候，可能会存在乱码的情况，主要原因是window的命令行与pycharm的编码不匹配。可以直接使用命令行来操作。
    windows使用时，还需要打开 Windows Time服务，如果没有开启服务，w32tm命令无法使用。
    """
    try:
        subprocess.run(['w32tm', '/resync'], check=True, timeout=5)
        print('时间已同步')
    except subprocess.TimeoutExpired as e:
        print('时间同步超时:', str(e))
    except Exception as e:
        print('时间同步失败:', str(e))


def main():
    while True:
        # ===sleep直到该时间
        sleep_until_run_time('12h', if_sleep=True, cheat_seconds=0)  # 每12h运行一次

        # ===根据当前系统执行不同的同步时间操作
        os_type = platform.system()
        if os_type == 'Windows':  # win执行
            sync_time_windows()
        elif os_type == 'Linux' or os_type == 'Darwin':  # linux和mac执行
            sync_time_ntp()
        else:
            print('不支持的操作系统类型')


if __name__ == "__main__":
    while True:
        try:
            main()
        except Exception as err:
            msg = '同步时间脚本出错，10s之后重新运行，出错原因: ' + str(err)
            print(msg)
            print(traceback.format_exc())
            send_wechat_work_msg(msg, error_webhook_url)
            time.sleep(10)
